SuperStrict

Rem
bbdoc: RAD Module
about: This modules provides some simple implementations of some of my old favorite
       3DRAD convenience functions.
End Rem
Module jmd.rad

ModuleInfo "Version: 1.0"
ModuleInfo "Author: Jonathan Decker"
ModuleInfo "License: GNU GPL v3"
ModuleInfo "SVN: http://blitzmax-rad-module.googlecode.com/svn/trunk/"

ModuleInfo "History: 1.0"
ModuleInfo "	Initial release."

Import brl.math

Rem
bbdoc: Linear interpolation
returns: an integer value between @retMin and @retMax
about:
Interpolate @value (which is between @vMin and @vMax) to be in the range of @retMin and @retMax.

Example:
&{
this:int = interpolate(10,1,10,1,100) ' results in 100 being returned
}

see also: #interpolateFloat()
End Rem
Function interpolate:Int(value:Int,vMin:Int,vMax:Int,retMin:Int,retMax:Int)
	Return retMin+((value-vMin)*(retMax-retMin)) / (vMax-vMin)
End Function


Rem
bbdoc: Linear interpolation
returns: an floating point value between @retMin and @retMax
about:
Interpolate @value (which is between @vMin and @vMax) to be in the range of @retMin and @retMax.

Example:
&{
this:Float = interpolateFloat(5.0,1.0,10.0,1.0,100.0) ' results in 50.0 being returned
}

see also: #interpolate()
End Rem
Function interpolateFloat:Float(value:Float,vMin:Float,vMax:Float,retMin:Float,retMax:Float)
	Return retMin+((value-vMin)*(retMax-retMin)) / (vMax-vMin)
End Function



Rem
bbdoc: Limit value 
returns: an integer clamped between @vMin and @vMax
about: 
If @value is between @vMin and @vMax, then @value is returned.
If @value is less than @vMin, then @vMin is returned.
If @value is greater than @vMax, then @vMax is returned.

Example:
&{
this:int=limit(this,1,100) 'clamps this to be between 1 and 100
}

see also: #limitFloat()
End Rem
Function limit:Int(value:Int,vMin:Int,vMax:Int)
	If value>vMax Then value=vMax
	If value<vMin Then value=vMin
	Return value
End Function

Rem
bbdoc: Limit value 
returns: a float clamped between @vMin And @vMax
about: 
If @value is between @vMin And @vMax, Then @value is returned.
If @value is less than @vMin, Then @vMin is returned.
If @value is greater than @vMax, Then @vMax is returned.

Example:
&{
this:Float=limitFloat(this,1,100) 'clamps this to be between 1 and 100
}

see also: #limit()
End Rem
Function limitFloat:Float(value:Float,vMin:Float,vMax:Float)
	If value>vMax Then value=vMax
	If value<vMin Then value=vMin
	Return value
End Function

Rem
bbdoc: See if a value is between a range
returns: @True or @False
about:
Return @true if @value is between @vMin and @vMax, otherwise return @false

Example:
&{
if between(this,1,100) then print "this is between 1 and 100!"
}

see also: #betweenFloat()
End Rem
Function between:Int(value:Int,vMin:Int,vMax:Int)
	If value<vMin
		Return False
	Else If value>vMax
		Return False
	Else
		Return True
	EndIf
End Function

Rem
bbdoc: See if a value is between a range
returns: @True or @False
about:
Return @true if @value is between @vMin and @vMax, otherwise return @false

Example:
&{
if between(this,1,100) then print "this is between 1 and 100!"
}

see also: #between()
End Rem
Function betweenFloat:Int(value:Float,vMin:Float,vMax:Float)
	If value<vMin
		Return False
	Else If value>vMax
		Return False
	Else
		Return True
	EndIf
End Function

Rem
bbdoc: wrap a value 
returns: an @Int between @vMin and @vMax
about: Wrap @value around @vMin and @vMax and return that value.

example:
&{
this:int = wrap(15,1,10) 'results in this=5
}

see also: #wrapFloat()
End Rem
Function wrap:Int(value:Int,retMin:Int,retMax:Int)
	Return retMin + (value Mod ((retMax+1)-retMin)) 
End Function


Rem
bbdoc: wrap a value 
returns: a @Float between @vMin and @vMax
about: Wrap @value around @vMin and @vMax and return that value.

example:
&{
this:Float = wrapFloat(15.0,1.0,10.0) 'results in this=5
}

see also: #wrap()
End Rem
Function wrapFloat:Float(value:Int,retMin:Float,retMax:Float)
	Return retMin + (value Mod ((retMax+1)-retMin)) 
End Function

Rem
bbdoc: Return a sinus value 
returns: a @Float sinus value
about:
The @retMin parameter is the minim sinus value
The @retMax parameter is the maximum sinus value
The @speed  parameter is the amount of time in milliseconds for one cycle to complete
The @offset parameter is  an offset, in degrees, added to the sinus value

Returns a sinus wave between vMin and vMax at the specified frequency. The @speed parameter
is the duration in milliseconds to complete one cycle. Hertz can easily be used instead with a
simple formulat of: milli:=1000/hertz, as shown in the next example:
&{
hz:int=1000/15 '15hz
thisVar:float = Oscillate(0,100,hz,0) '15hz oscillation
}

Below is a more complete example of how #Oscillate() and its parameters can be used
End Rem
Function Oscillate:Float(retMin:Float,retMax:Float,speed:Float,offset:Float)
	Return retMin+((retMax-retMin)/2) * Sin( ((MilliSecs()/speed/2)*(1000/2))+offset ) + (retMax-RetMin)/2
End Function

Rem
bbdoc: rebound a value with elasticity
returns: an inverted and dampened @Float value
about: Rebound a value with elasticity. The optional @deadband parameter will force the returned
value to 0 if within the deadband. See example of bouncing ball below:

Note: elasticity values should normally be below 1.0, but values above 1.0 become "super-elastic"
and rebound with more force than the initial value.
End Rem
Function Rebound:Float(value:Float,elasticity:Float,deadband:Float=0.1)
	Local retval:Float
	retval = value*-1*elasticity
	If between(retval,-deadband,deadband) Then retVal=0
	Return retval
End Function